/*
 * MISC.C Version 1.01 (C)1996 HUDSON SOFT
 * MIX 再生サンプルプログラム一般関数群(MISC.C)
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <dos.h>
#include <dir.h>
#include "mixplay.h"

/* デバッグモードの場合にのみメッセージを表示します。
 *
 * 入力
 * char		    *fmt   printfフォーマット文字列
 * ...		    ...    引数
 *
 * 出力
 * なし
 */
void dprintf(char *fmt, ...)
{
    va_list arg;
    if (debug_flag) {
	va_start(arg,fmt);
	vprintf(fmt,arg);
	va_end(arg);
    }
}

/* ファイルの存在チェックを行います。
 *
 * 入力
 * char		    *file  チェックするファイル名
 *
 * 出力
 * int		    0      ファイルが存在しない
 *		    0 以外 ファイルが存在する
 */
int file_exist_check(char *file)
{
    struct find_t fb;
    if (_dos_findfirst(file,_A_NORMAL,&fb)) return(FALSE);
    if (fb.attrib & (_A_VOLID | _A_SUBDIR)) return(FALSE);
    return(TRUE);
}

/* ファイルの長さを調べます。
 *
 * 入力
 * char		    *file  調べるファイル名
 *
 * 出力
 * unsigned long	   ファイルの長さ
 */
unsigned long get_file_size(char *file)
{
    struct find_t fb;
    if (_dos_findfirst(file,_A_NORMAL,&fb)) return(0L);
    if (fb.attrib & (_A_VOLID | _A_SUBDIR)) return(0L);
    return(fb.size);
}

/* ２桁の BCD 数値を通常の数値に変換します。
 *
 * 入力
 * int              bcd    BCD 数値
 *
 * 出力
 * int		    0 以上 変換した数値
 *		    負の数 変換できない
 */
int bcd2bin(int bcd)
{
    int rs;
    rs = (bcd >> 4);
    if (rs > 9) return(-1);
    bcd &= 0x0f;
    if (bcd > 9) return(-1);
    return(rs * 10 + bcd);
}

/* 通常の数値を２桁の BCD 数値に変換します。
 *
 * 入力
 * int              bcd    通常の数値
 *
 * 出力
 * int		    0 以上 変換した BCD 数値
 *		    負の数 変換できない
 */
int bin2bcd(int bin)
{
    int rs;
    if ((bin < 0) | (bin > 99)) return(-1);
    rs = bin / 10;
    bin %= 10;
    return((rs << 4) + bin);
}

/* DOS からメモリを確保します。
 *
 * 入力
 * unsigned long    sz     確保するサイズ
 *
 * 出力
 * void far *	    NULL   確保できない
 *		    上記外 確保したメモリのポインタ
 */
void far *my_malloc(unsigned long sz)
{
    unsigned int psz,seg;
    psz = ((sz + 15L) >> 4) & 0xffff;
    if (!psz) return((void far *)NULL);
    if (_dos_allocmem(psz,&seg) != 0) return((void far *)NULL);
    return(MK_FP(seg,0));
}

/* DOS から確保したメモリを開放します。
 *
 * 入力
 * void far         *ptr   開放するメモリ
 *
 * 出力
 * なし
 */
void my_free(void far *ptr)
{
    _dos_freemem(FP_SEG(ptr));
}

/* ファイルをシークします。
 *
 * 入力
 * int		    fhd    シークするファイルハンドラ
 * long		    ofs    シークオフセット
 * int		    from   シークの基準点
 *
 * 出力
 * なし
 */
void my_seek(int fhd,long ofs,int from)
{
    asm push bx
    asm push cx
    asm mov bx,fhd
    asm mov ax,from
    asm mov ah,042h
    asm mov dx,word ptr ofs
    asm mov cx,word ptr ofs+2
    asm int 21h
    asm pop cx
    asm pop bx
}

/* デバイスに対しIOCTLを実行します。
 *
 * 入力
 * int		    fhd    IOCTLするファイルハンドラ
 * int		    fnc    IOCTL機能番号
 * void far	    *ptr   データポインタ
 * int		    len    データ長
 *
 * 出力
 * int		    ??     転送長
 */
int my_ioctl(int fhd,int fnc,void far *buf,int len)
{
    asm push ds
    asm push bx
    asm push cx
    asm mov bx,fhd
    asm mov ax,fnc
    asm mov ah,044h
    asm mov cx,len
    asm lds dx,buf
    asm int 21h
    asm jnc my_ioctl_ok
    asm sbb ax,ax
my_ioctl_ok:
    asm pop cx
    asm pop bx
    asm pop ds
    return(_AX);
}

/* パス名のドライブ名、ディレクトリ名を残し、主ファイル名、拡張子名を入れ替えま
 * す。
 *
 * 入力
 * char		    *src   元のパス名
 * char		    *name  新しい主ファイル名
 * char		    *ext   新しい拡張子名
 * char		    *buf   新パス名の格納ポインタ
 *
 * 出力
 * なし
 */
void change_file_ext(char *src,char *name,char *ext,char *buf)
{
    char drive[MAXDRIVE];
    char dir[MAXDIR];
    fnsplit(src,drive,dir,NULL,NULL);
    fnmerge(buf,drive,dir,name,ext);
}
